#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

/*
 * 钩子函数，在线程结束的时候调用
 * */
static void cleanup(void *arg)
{

	puts(arg);

}

static void *task(void *arg)
{
	puts("children thread is working! \n");


	/*
	 * 注册钩子函数，其中pthread_cleanup_push() 和 pthread_cleanup_pop(),是成对出现，因此他们展开宏，如果不匹配会造成语法错误。
	 * pthread_cleanup_pop(参数一)，参数一：表示是否调用已经注册的钩子函数，1:表示调用，0:表示不调用
	 * */
	pthread_cleanup_push(cleanup, "cheanup:1");
	pthread_cleanup_push(cleanup, "cheanup:2");
	pthread_cleanup_push(cleanup, "cheanup:3");
	puts("push over!");

	// 表示是否对钩子函数进行调用
	pthread_cleanup_pop(1);
	pthread_cleanup_pop(0);
	pthread_cleanup_pop(1);

	// 线程的退出，最好使用pthread_exit()，可以对线程资源进行回收。
	pthread_exit(NULL);
	//return NULL;
}

/*
 * 线程栈的清理
 * */
int main(int argc, char **argv)
{
	pthread_t tid;
	int tret;
	
	puts("---------------begin!!!\n");
	
	tret = pthread_create(&tid, NULL, task, NULL);
	if(tret)
	{
		// 线程创建失败
		fprintf(stderr, "pthread_create() is failed, error : %s \n",strerror(tret));
		exit(1);
	}

	// 会给线程收尸，等待线程执行结束，第二个参数NULL，表示从pthread_exit(NULL)返回的状态，可以使用一个指针的地址进行接收
	pthread_join(tid, NULL);

	puts("---------------end!!!\n");

	exit(0);
}
